from ucimlrepo import fetch_ucirepo
import pandas as pd
import numpy as np

# 获取数据集
heart_disease = fetch_ucirepo(id=45)

# 获取特征和目标变量
X = heart_disease.data.features
y = heart_disease.data.targets

# 1. 数据描述
print("="*50)
print("数据描述")
print("="*50)
print("数据集形状:", X.shape)
print("目标变量形状:", y.shape)
print("\n特征数据描述统计:")
print(X.describe())
print("\n目标变量描述统计:")
print(y.describe())

# 检查缺失值
print("\n缺失值统计:")
missing_values = X.isnull().sum()
print(missing_values[missing_values > 0])

# 2. 数据清洗
print("\n"+"="*50)
print("数据清洗")
print("="*50)

# 处理缺失值
X_cleaned = X.copy()
# 对数值型特征使用均值填充
numeric_cols = X_cleaned.select_dtypes(include=['int64', 'float64']).columns
X_cleaned[numeric_cols] = X_cleaned[numeric_cols].fillna(X_cleaned[numeric_cols].mean())
# 对分类特征使用众数填充
categorical_cols = X_cleaned.select_dtypes(include=['object']).columns
for col in categorical_cols:
    X_cleaned[col] = X_cleaned[col].fillna(X_cleaned[col].mode()[0])

print("清洗后的缺失值统计:")
print(X_cleaned.isnull().sum().sum())

# 3. 数据转换
print("\n"+"="*50)
print("数据转换")
print("="*50)

# 将分类变量转换为数值
X_transformed = X_cleaned.copy()
# 获取分类特征列表
categorical_cols = X_transformed.select_dtypes(include=['object']).columns
# 使用独热编码
X_transformed = pd.get_dummies(X_transformed, columns=categorical_cols, drop_first=True)
print("转换后的数据形状:", X_transformed.shape)
print("转换后的特征列:", X_transformed.columns.tolist())

# 4. 数据规约
print("\n"+"="*50)
print("数据规约")
print("="*50)

# 选择重要特征 - 使用英文列名
important_features = ['age', 'sex', 'cp', 'trestbps', 'chol', 'thalach', 'oldpeak']
X_reduced = X_cleaned[important_features]
print("规约后的数据形状:", X_reduced.shape)
print("规约后的特征列:", X_reduced.columns.tolist())

# 5. 数据离散化
print("\n"+"="*50)
print("数据离散化")
print("="*50)

X_discretized = X_reduced.copy()
# 将年龄分为几个区间
X_discretized['age_group'] = pd.cut(X_discretized['age'], 
                              bins=[0, 40, 50, 60, 70, 100], 
                              labels=['40岁以下', '40-50岁', '50-60岁', '60-70岁', '70岁以上'])
# 将血压分为几个区间
X_discretized['bp_group'] = pd.cut(X_discretized['trestbps'], 
                              bins=[0, 120, 140, 160, 200], 
                              labels=['正常', '轻度高血压', '中度高血压', '重度高血压'])
# 将胆固醇分为几个区间
X_discretized['chol_group'] = pd.cut(X_discretized['chol'], 
                               bins=[0, 200, 240, 300, 600], 
                               labels=['正常', '边缘高', '高', '非常高'])

print("离散化后的数据形状:", X_discretized.shape)
print("离散化后的特征列:", X_discretized.columns.tolist())
print("\n离散化后的数据示例:")
print(X_discretized.head())

# 6. 多维分析
print("\n"+"="*50)
print("多维分析")
print("="*50)

# 合并特征和目标变量
data_for_analysis = X_discretized.copy()
data_for_analysis['heart_disease'] = y

# 按性别分析心脏病发病率
gender_analysis = data_for_analysis.groupby('sex')['heart_disease'].agg(['mean', 'count']).reset_index()
gender_analysis.columns = ['性别', '心脏病发病率', '样本数']
print("\n按性别分析心脏病发病率:")
print(gender_analysis)

# 按年龄分组分析心脏病发病率
age_analysis = data_for_analysis.groupby('age_group')['heart_disease'].agg(['mean', 'count']).reset_index()
age_analysis.columns = ['年龄分组', '心脏病发病率', '样本数']
print("\n按年龄分组分析心脏病发病率:")
print(age_analysis)

# 按胸痛类型分析心脏病发病率
cp_analysis = data_for_analysis.groupby('cp')['heart_disease'].agg(['mean', 'count']).reset_index()
cp_analysis.columns = ['胸痛类型', '心脏病发病率', '样本数']
print("\n按胸痛类型分析心脏病发病率:")
print(cp_analysis)

# 按血压分组分析心脏病发病率
bp_analysis = data_for_analysis.groupby('bp_group')['heart_disease'].agg(['mean', 'count']).reset_index()
bp_analysis.columns = ['血压分组', '心脏病发病率', '样本数']
print("\n按血压分组分析心脏病发病率:")
print(bp_analysis)

# 按胆固醇分组分析心脏病发病率
chol_analysis = data_for_analysis.groupby('chol_group')['heart_disease'].agg(['mean', 'count']).reset_index()
chol_analysis.columns = ['胆固醇分组', '心脏病发病率', '样本数']
print("\n按胆固醇分组分析心脏病发病率:")
print(chol_analysis)

# 多维交叉分析：性别和年龄分组
gender_age_analysis = data_for_analysis.groupby(['sex', 'age_group'])['heart_disease'].agg(['mean', 'count']).reset_index()
gender_age_analysis.columns = ['性别', '年龄分组', '心脏病发病率', '样本数']
print("\n按性别和年龄分组交叉分析心脏病发病率:")
print(gender_age_analysis)

# 多维交叉分析：胸痛类型和血压分组
cp_bp_analysis = data_for_analysis.groupby(['cp', 'bp_group'])['heart_disease'].agg(['mean', 'count']).reset_index()
cp_bp_analysis.columns = ['胸痛类型', '血压分组', '心脏病发病率', '样本数']
print("\n按胸痛类型和血压分组交叉分析心脏病发病率:")
print(cp_bp_analysis)

# 计算相关性
print("\n特征之间的相关性分析:")
numeric_data = data_for_analysis.select_dtypes(include=['int64', 'float64'])
correlation = numeric_data.corr()
print(correlation['heart_disease'].sort_values(ascending=False))

print("\n"+"="*50)
print("分析总结")
print("="*50)
print("1. 数据集包含 {} 个样本和 {} 个特征。".format(X.shape[0], X.shape[1]))
print("2. 通过数据预处理，我们清洗了缺失值，转换了分类变量，并进行了特征规约和离散化。")
print("3. 多维分析显示了不同特征与心脏病发病率之间的关系。")
print("4. 相关性分析揭示了哪些特征与心脏病诊断最相关。")
